﻿#include <iostream>                 // 输入输出流
#include <vector>                   // 向量容器，用于线程池存储线程
#include <queue>                    // 队列容器，用于任务队列
#include <thread>                   // std::thread 支持多线程
#include <future>                   // std::future 和 std::packaged_task
#include <mutex>                    // std::mutex 用于互斥锁
#include <condition_variable>       // 条件变量，用于线程同步
#include <functional>               // std::function 包装可调用对象
// 线程池类定义
class ThreadPool {
public:
    ThreadPool(size_t threads);     // 构造函数，传入线程数量
    ~ThreadPool();                  // 析构函数，销毁线程池
    // 添加任务接口，使用模板函数接收任意可调用对象
    template<class F>
    auto enqueue(F f) -> std::future<decltype(f())>;
private:
    std::vector<std::thread> workers;               // 工作线程集合
    std::queue<std::function<void()>> tasks;        // 任务队列（存储待执行的函数）
    std::mutex queue_mutex;                         // 任务队列的互斥锁
    std::condition_variable condition;              // 条件变量，用于任务通知
    bool stop;                                      // 是否停止线程池
};
// 构造函数：初始化线程池并创建指定数量的线程
ThreadPool::ThreadPool(size_t threads) : stop(false) {
    for (size_t i = 0; i < threads; ++i)
        workers.emplace_back([this]() {
            for (;;) {
                std::function<void()> task;
                {
                    // 加锁保护任务队列
                    std::unique_lock<std::mutex> lock(this->queue_mutex);
                    // 等待任务队列不为空，或线程池被停止
                    this->condition.wait(lock,
                                         [this]() { return this->stop || !this->tasks.empty(); });
                    // 如果线程池被停止且没有任务，则退出线程
                    if (this->stop && this->tasks.empty()) return;
                    // 取出任务
                    task = std::move(this->tasks.front());
                    this->tasks.pop();
                }
                // 执行任务
                task();
            }
        });
}
// 添加任务的接口
template<class F>
auto ThreadPool::enqueue(F f) -> std::future<decltype(f())> {
    // 将传入的函数 f 封装为 packaged_task
    auto task = std::make_shared<std::packaged_task<decltype(f())()>>(f);
    // 获取 future，用于获取任务结果
    std::future<decltype(f())> res = task->get_future();
    {
        // 加锁并将任务添加到队列
        std::unique_lock<std::mutex> lock(queue_mutex);
        tasks.emplace([task]() { (*task)(); }); // 包装成 void() 类型后入队
    }
    // 通知一个等待中的线程
    condition.notify_one();
    return res; // 返回 future
}
// 析构函数：停止线程池并回收所有线程资源
ThreadPool::~ThreadPool() {
    {
        std::unique_lock<std::mutex> lock(queue_mutex);
        stop = true; // 设置停止标志
    }
    // 通知所有线程
    condition.notify_all();
    // 等待所有线程结束
    for (std::thread &worker : workers)
        worker.join();
}
// ---------------- 主函数测试 ----------------
int main() {
    // 创建线程池，包含 4 个工作线程
    ThreadPool pool(4);
    // 用来保存每个任务的 future 结果
    std::vector<std::future<int>> results;
    // 向线程池中添加 8 个任务
    for (int i = 0; i < 8; ++i) {
        results.emplace_back(
                pool.enqueue([i] {
                    // 模拟每个任务执行需要 500 毫秒
                    std::this_thread::sleep_for(std::chrono::milliseconds(500));
                    // 输出当前任务编号和运行该任务的线程ID
                    std::cout << "renwu " << i << " run xiancheng "
                              << std::this_thread::get_id() << std::endl;
                    return i * i; // 返回 i 的平方
                })
        );
    }
    // 获取并打印所有任务执行结果
    for (auto& res : results) {
        std::cout << "renwu result: " << res.get() << std::endl;
    }
    return 0;
}
